package com.docshell.main;

import java.util.StringTokenizer;

import com.docshell.common.DisplayManager;
import com.docshell.common.SessionManager;
import com.docshell.constants.DocShellConstants;
import com.docshell.exceptions.DocShellException;
import com.docshell.service.CommandHandler;

public class DocShell {
	
	private static String m_StartupFolder = null;
	
	public static void main(String[] args) {
		String docbase = null;
		String username = null;
		String password = null;
		String folder = null;
		String infile = null;
		String outfile = null;
		
		try {
			for (int i = 0; i < args.length; i++) {
				String arg = args[i];
				if ("-d".equals(arg.substring(0,2))) {
					docbase = arg.substring(2);
				}
				if ("-u".equals(arg.substring(0,2))) {
					username = arg.substring(2);
				}
				if ("-p".equals(arg.substring(0,2))) {
					password = arg.substring(2);
				}
				if ("-f".equals(arg.substring(0,2))) {
					folder = arg.substring(2);
				}
				if ("-i".equals(arg.substring(0,2))) {
					infile = arg.substring(2);
				}
				if ("-o".equals(arg.substring(0,2))) {
					outfile = arg.substring(2);
				}
			}		
			
			if (username!=null) SessionManager.setUserName(username);
			if (password!=null) SessionManager.setPassword(password);
			if (docbase!=null) SessionManager.setDocbase(docbase);
			if (infile!=null) DisplayManager.setinFile(infile);
			if (outfile!=null) DisplayManager.setoutFile(outfile);
			m_StartupFolder = (folder!=null) ? folder : "";
			
			DisplayManager.initialize();
			
			DocShell docshell = new DocShell();
			docshell.welcome();
			docshell.processCommands();
			
		}
		catch (DocShellException dse) {
			System.out.println(DocShellException.UNKNOWN_EXCEPTION);
			dse.printStackTrace();
		}
		catch (Exception ex) {
			System.out.println(DocShellException.UNKNOWN_EXCEPTION);
			ex.printStackTrace();			
		}
		finally {
			SessionManager.cleanUp();
		}
	}
	
	private void welcome() throws DocShellException {
		DisplayManager.writeLine(DocShellConstants.WELCOME_MESSAGE);
		DisplayManager.writeLine(DocShellConstants.VERSION_NUMBER);
		DisplayManager.writeLine(DocShellConstants.BUILD_NUMBER);		
	}

	private void processCommands() throws DocShellException {
		try {
			
			CommandHandler cmdHandler = new CommandHandler(); 
			cmdHandler.initialize(m_StartupFolder);
			
			String commandLine = null;
			int lineNumber = 1;
			int liActionFlag = DocShellConstants.ACT_DO_NOTHING;
			while((commandLine = DisplayManager.getLine()) != null) {
				StringTokenizer st = new StringTokenizer(commandLine,",");
				if (st.countTokens() == 0) {
					continue;
				}
				String command = st.nextToken();
	
				if (lineNumber==1) {
					cmdHandler.checkCommandType(command);
					if (command.equalsIgnoreCase(DocShellConstants.EXIT_COMMAND) || command.equalsIgnoreCase(DocShellConstants.QUIT_COMMAND)) {
						liActionFlag = DocShellConstants.ACT_QUIT;
					}
				}
				switch (cmdHandler.getCommandType()) {
				case DocShellConstants.UNKNOWN_COMMAND: // Unknown command
					cmdHandler.displayCommandError(DocShellConstants.NOT_A_SUPPORTED_COMMAND);
					break;
				case DocShellConstants.INTERNAL_COMMAND: // Internal command
					if (liActionFlag!=DocShellConstants.ACT_QUIT) {
						cmdHandler.appendCommand(commandLine);
						if (cmdHandler.getNumOfLines()==lineNumber) {
							liActionFlag = DocShellConstants.ACT_EXECUTE;
						}
						else {
							liActionFlag = DocShellConstants.ACT_GOTO_NEXTLINE;
						}
					}
					break;
				case DocShellConstants.API_COMMAND: // API
					cmdHandler.appendCommand(commandLine);
					if (cmdHandler.getNumOfLines()==lineNumber) {
						liActionFlag = DocShellConstants.ACT_EXECUTE;
					}
					else {
						liActionFlag = DocShellConstants.ACT_GOTO_NEXTLINE;
					}
					break;
				case DocShellConstants.DQL_COMMAND: // DQL
					if (command.equalsIgnoreCase(DocShellConstants.COMMAND_TERMINATOR)) {
						liActionFlag = DocShellConstants.ACT_EXECUTE;
					}
					else {
						cmdHandler.appendCommand(commandLine);
						liActionFlag = DocShellConstants.ACT_GOTO_NEXTLINE;
					}
					break;
				}

				switch (liActionFlag) {
				case DocShellConstants.ACT_DO_NOTHING:
					break;
				case DocShellConstants.ACT_QUIT:
					DisplayManager.writeLine(DocShellConstants.GOODBYE_MESSAGE);
					return;
				case DocShellConstants.ACT_GOTO_NEXTLINE:
					lineNumber++;
					if (cmdHandler.getCommandType()==DocShellConstants.DQL_COMMAND) 
						DisplayManager.setPrompt(String.valueOf(lineNumber));
					break;
				case DocShellConstants.ACT_EXECUTE:
					cmdHandler.execute();
					lineNumber = 1;
					cmdHandler.resetPrompt();
					liActionFlag = DocShellConstants.ACT_DO_NOTHING;
					break;
				}
			}

		} catch (DocShellException dsex) {
			throw new DocShellException(DocShellException.UNKNOWN_EXCEPTION, dsex.toString());
		} catch (Exception ex) {
			throw new DocShellException(DocShellException.UNKNOWN_EXCEPTION, ex.toString());
		}
	}
}
